#include "MonkeyRuntime.h"
#include "MonkeyExceptions.h"
#include "MonkeyContext.h"

static MonkeyRuntime *_sharedRuntime;


//
// Initialize a new monkey runtime object.
//
MonkeyRuntime::MonkeyRuntime()
{
    runtime = JS_NewRuntime(8L * 1024L * 1024L);
    if (runtime == NULL)
        throw GenericException("Could not create JS runtime.");
}


//
// Destroy a Monkey Runtime object.
//
MonkeyRuntime::~MonkeyRuntime()
{
    std::list<MonkeyContext *>::iterator it;
    
    
    //
    // Destroy all the contexts.
    //
    while (!contexts.empty())
    {
        DestroyContext(*contexts.begin());
    }
    
    JS_DestroyRuntime(runtime);
    if (_sharedRuntime == this)
        _sharedRuntime = NULL;
    
    JS_ShutDown();
}


//
// Retrieve the shared runtime environment.
//
MonkeyRuntime *MonkeyRuntime::SharedRuntime()
{
    if (_sharedRuntime != NULL)
        return _sharedRuntime;

    return new MonkeyRuntime();
}


//
// Create a new context that will be used with this runtime.
//
MonkeyContext *MonkeyRuntime::CreateContext()
{
    MonkeyContext *ctx = new MonkeyContext(this);
    
    contexts.push_back(ctx);
    
    return ctx;
}


//
// Destroy the context and remove it from the runtime.
//
void MonkeyRuntime::DestroyContext(MonkeyContext *ctx)
{
    contexts.remove(ctx);
    
    delete ctx;
}

